本文源码请见我的GitHub
2.3 Numpy 数组的计算:通用函数
numpy数组计算有时候会很慢,使之边块的关键是利用向量化操作,通常在通用函数(ufunc)中实现。
2.3.1 缓慢的循环
Python在每次循环首先检查对象的类型,并且动态查找可以使用该数据类型的正确函数。Cpython在每次循环时必须做数据类型的检查和函数的调度。如果在编译代码是进行这样操作,就能在代码执行前知晓类型的生命,结果的计算也会更加有效率。
2.3.3 探索Numpy的通用函数
一般有两种存在形式:一元通用函数,对单个输入操作;二元通用函数。
1.数组的运算
标准的加减乘除都可以使用
1 | import numpy as np |
1 | x = np.arange(4) |
x = [0 1 2 3]
x + 5 = [5 6 7 8]
x - 5 = [-5 -4 -3 -2]
x * 2 = [0 2 4 6]
X / 2 = [0. 0.5 1. 1.5]
x // 2 = [0 0 1 1]
1 | #逻辑非、 **表示的指数运算符和%表示的模运算符的一元通用函数: |
1 | print("-x =", -x) |
-x = [ 0 -1 -2 -3]
x ** 2 = [0 1 4 9]
x % 2 = [0 1 0 1]
所有这些运算符都是Numpy内置函数的简单封装器
2.绝对值
1 | x = np.array([1,-22,3,-4]) |
array([ 1, 22, 3, 4])
1 | np.absolute(x) |
array([ 1, 22, 3, 4])
这个函数也可以处理复数。 绝对值返回的是该复数的幅度:
1 | x = np.array([3 - 4j, 4-3j,6 + 8j]) |
array([ 5., 5., 10.])
3.三角函数
1 | theta = np.linspace(0, np.pi, 3) |
1 | print("theta = ",theta) |
theta = [0. 1.57079633 3.14159265]
sin(theta) = [0.0000000e+00 1.0000000e+00 1.2246468e-16]
cos(theta) = [ 1.000000e+00 6.123234e-17 -1.000000e+00]
tan(theta) = [ 0.00000000e+00 1.63312394e+16 -1.22464680e-16]
逆三角函数也是可以用的
1 | print("theta = ",theta) |
theta = [0. 1.57079633 3.14159265]
arcsin(theta) = [ 0. nan nan]
arccos(theta) = [1.57079633 nan nan]
arctan(theta) = [0. 1.00388482 1.26262726]
D:\Software\Anaconda3\lib\site-packages\ipykernel_launcher.py:2: RuntimeWarning: invalid value encountered in arcsin
D:\Software\Anaconda3\lib\site-packages\ipykernel_launcher.py:3: RuntimeWarning: invalid value encountered in arccos
This is separate from the ipykernel package so we can avoid doing imports until
4.指数和对数
1 | x = [1,2,3] |
x = [1, 2, 3]
e^x = [ 2.71828183 7.3890561 20.08553692]
2^x = [2. 4. 8.]
3^x = [ 3 9 27]
1 | x = [1,2,4,10] |
x = [1, 2, 4, 10]
ln(x) = [0. 0.69314718 1.38629436 2.30258509]
log2(x) = [0. 1. 2. 3.32192809]
log10(x) = [0. 0.30103 0.60205999 1. ]
2.3.4 高级的通用函数特性
1.指定输出
1 | x =np.arange(5) |
[ 0. 10. 20. 30. 40.]
也可以用作数组视图,例如可以将计算结果写入指定数组的每隔一个元素的位置
1 | y = np.zeros(10) |
[ 1. 0. 2. 0. 4. 0. 8. 0. 16. 0.]
2.聚合
如果用特定的运算reduce一个数组。那么可以用任何通用函数的reduce方法。
1 | x = np.arange(1,6) |
15
1 | np.multiply.reduce(x)#所有元素的成绩 |
120
1 | np.add.accumulate(x)#需要存储每次计算的中间结果 |
array([ 1, 3, 6, 10, 15], dtype=int32)
1 | np.multiply.accumulate(x) |
array([ 1, 2, 6, 24, 120], dtype=int32)
3.外积
1 | x = np.arange(1,6) |
array([[ 1, 2, 3, 4, 5],
[ 2, 4, 6, 8, 10],
[ 3, 6, 9, 12, 15],
[ 4, 8, 12, 16, 20],
[ 5, 10, 15, 20, 25]])